package com.example.my_self_view.practice1

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import com.example.my_self_view.R

class DoubleColorRingProgress: View {

    private val defaultPaint by lazy { Paint() }
    private val displayPaint by lazy { Paint() }
    private val defaultTextPaint by lazy { Paint() }
    private val displayTextPaint by lazy { Paint() }
    private val rect by lazy { Rect() }
    private val rectF by lazy { RectF() }

    private var ringRadius = valueToPx(50f, TypedValue.COMPLEX_UNIT_DIP)
    private var currentProgress = 0
    private var maxProgress = 100

    fun setCurrentProgress(current: Int) {
        this.currentProgress = current
        invalidate()
    }

    fun setMaxProgress(max: Int) {
        this.maxProgress = max
    }

    fun setDefaultColor(color: Int) {
        defaultPaint.color = color
    }

    fun setDisplayColor(color: Int) {
        displayPaint.color = color
    }

    constructor(context: Context): this(context, null) {}

    constructor(context: Context, attrs: AttributeSet?): this(context, attrs, 0) {}

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int): this(context, attrs, defStyleAttr, 0) {}

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int): super(context, attrs, defStyleAttr, defStyleRes) {
        initAttrs(context, attrs)
    }

    private fun initAttrs(context: Context, attrs: AttributeSet?) {
        val typedArray =
            context.obtainStyledAttributes(attrs, R.styleable.DoubleColorRingProgress)
        typedArray.apply {
            try {
                ringRadius = typedArray.getDimension(R.styleable.DoubleColorRingProgress_ringRadius, ringRadius)
                val ringWidth = typedArray.getDimension(R.styleable.DoubleColorRingProgress_ringWidth, valueToPx(1f, TypedValue.COMPLEX_UNIT_DIP))
                // 默认状态
                val defaultColor = typedArray.getColor(R.styleable.DoubleColorRingProgress_defaultColor, Color.BLACK)
                defaultPaint.apply {
                    isAntiAlias = true
                    isDither = true
                    color = defaultColor
                    strokeWidth = ringWidth
                    style = Paint.Style.STROKE
                }
                // 展示状态
                val displayColor = typedArray.getColor(R.styleable.DoubleColorRingProgress_displayColor, Color.RED)
                displayPaint.apply {
                    isAntiAlias = true
                    isDither = true
                    color = displayColor
                    strokeWidth = ringWidth
                    style = Paint.Style.STROKE
                }
                // 默认文字
                val textSize = typedArray.getDimension(R.styleable.DoubleColorRingProgress_progressTextSize, valueToPx(16f, TypedValue.COMPLEX_UNIT_SP))
                defaultTextPaint.apply {
                    isAntiAlias = true
                    isDither = true
                    color = defaultColor
                    this.textSize = textSize
                }
                // 展示文字
                displayTextPaint.apply {
                    isAntiAlias = true
                    isDither = true
                    color = displayColor
                    this.textSize = textSize
                }
            } finally {
                recycle()
            }
        }

    }

    private fun valueToPx(value: Float, unit: Int): Float {
        return TypedValue.applyDimension(unit, value, resources.displayMetrics)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        // 如果是RelativeLayout，则不管给没给width、height的准确值，都是AT_MOST
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)

        var width = MeasureSpec.getSize(widthMeasureSpec)
        if (widthMode == MeasureSpec.AT_MOST) {
            width = ( ringRadius * 2 ).toInt() + paddingStart + paddingEnd
        }

        var height = MeasureSpec.getSize(heightMeasureSpec)
        if (heightMode == MeasureSpec.AT_MOST) {
            height = ( ringRadius * 2 ).toInt() + paddingTop + paddingBottom
        }

        // 固定为正方形
        if (width >= height) width = height
        else height = width

        setMeasuredDimension(width, height)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        // 画默认环
        canvas.save()
        val cx = width.toFloat() / 2f
        val cy = height.toFloat() / 2f
        val radius = ringRadius - defaultPaint.strokeWidth / 2f
        canvas.drawCircle(cx, cy, radius, defaultPaint)
        canvas.restore()

        val text = "${currentProgress.toString()}%"
        displayTextPaint.getTextBounds(text, 0, text.length, rect) // 获取字体宽高

        val dx = width / 2 - rect.width() / 2
        val dl = dx
        var dr = dl + (currentProgress.toFloat() / maxProgress.toFloat()) * rect.width()
        val dt = height / 2 - rect.height() / 2
        val db = dt + rect.height()
        // 计算baseLine
        val fontMetricsInt = displayTextPaint.fontMetricsInt // 获取字体的基准值
        val dy = - (fontMetricsInt.top + fontMetricsInt.bottom) / 2
        val baseLine = height / 2 + dy

        // 画展示字
        canvas.save()
        //先裁剪，后画
        if (currentProgress == 100) dr = width / 2f + rect.width()
        canvas.clipRect(dl, dt, dr.toInt(), db)
        canvas.drawText(text, dx.toFloat(), baseLine.toFloat(), displayTextPaint)
        canvas.restore()

        // 画默认字
        canvas.save()
        canvas.clipRect(dr.toInt(), dt, width / 2 + rect.width(), db)
        canvas.drawText(text, dx.toFloat(), baseLine.toFloat(), defaultTextPaint)
        canvas.restore()

        // 画展示的弧
        canvas.save()
        rectF.apply {
            top = height.toFloat() / 2 - radius
            bottom = height.toFloat() / 2 + radius
            left = width.toFloat() / 2 - radius
            right = width.toFloat() / 2 + radius
        }
        val sweepAngle = (currentProgress.toFloat() / maxProgress.toFloat()) * 360f
        canvas.drawArc(rectF, 180f, sweepAngle, false, displayPaint)
        canvas.restore()
    }

    private fun drawText(canvas: Canvas, text: String, start: Float, end: Float, paint: Paint) {

    }
}